home *** CD-ROM | disk | FTP | other *** search
/ Programmer Power Tools / Programmer Power Tools.iso / database / com.c < prev    next >
Text File  |  1984-05-21  |  10KB  |  412 lines

  1. /* SDB - expression compiler
  2.     syntax:
  3.         <expr>          ::= <lor> <EOS>
  4.         <lor>           ::= <land> { '|' <land> }
  5.         <land>          ::= <relat> { '&' <relat> }
  6.         <relat>         ::= <primary> { <relop> <primary> }
  7.         <primary>       ::= <factor> | <unop> <unary>
  8.         <factor>        ::= <number> | <string> | '(' <query> ')'
  9.         <number>        ::= <digit> | <number> <digit>
  10.         <string>        ::= '"' <chars> '"'
  11.         <chars>         ::= nil | <chars> <character>
  12.         <relop>         ::= '=' | '<>' | '<' | '>' | '<=' | '>='
  13.         <unop>          ::= '+' | '-' | '~'
  14. */
  15.  
  16. #include "sdbio.h"
  17.  
  18. extern int dbv_token;
  19. extern char dbv_tstring[];
  20. extern int dbv_tvalue;
  21.  
  22. extern int db_xand();
  23. extern int db_xor();
  24. extern int db_xnot();
  25. extern int db_xlss();
  26. extern int db_xleq();
  27. extern int db_xeql();
  28. extern int db_xgeq();
  29. extern int db_xgtr();
  30. extern int db_xneq();
  31. extern int db_xpush();
  32. extern int db_xstop();
  33.  
  34. static union codecell code[CODEMAX+1];
  35. static int cndx;
  36. static struct sel *selptr;
  37.  
  38. /* compile - compile a boolean expression */
  39. int db_compile(slptr)
  40.   struct sel *slptr;
  41. {
  42.     int result,i;
  43.     union codecell *cptr;
  44. #ifdef Lattice
  45.     int (*dns)();  /*dns*/
  46. #endif
  47.  
  48.     /* save the selection structure pointer */
  49.     selptr = slptr;
  50.  
  51.     /* initialize the code array index */
  52.     cndx = 0;
  53.  
  54.     /* parse the boolean expression */
  55.     if (!expr(&result)) {
  56.         code[cndx++].c_operator = db_xstop;
  57.         freelit(code);
  58.         return (FALSE);
  59.     }
  60.  
  61.     /* terminate the code */
  62.     code[cndx++].c_operator = db_xstop;
  63.  
  64.     /* allocate space for the code array */
  65.     if ((cptr = malloc(sizeof(union codecell) * cndx)) == NULL) {
  66.         freelit(code);
  67.         return (FALSE);
  68.     }
  69.  
  70.     /* store the code into the code array */
  71.     slptr->sl_where = cptr;
  72.     for (i = 0; i < cndx; i++) {
  73.         (*cptr++).c_operator = code[i].c_operator;
  74. #ifndef Lattice
  75.         if (code[i].c_operator == db_xpush)
  76. #else
  77.         if ( code[i].c_operator == (dns=db_xpush) )  /*dns*/
  78. #endif
  79.             (*cptr++).c_operand = code[++i].c_operand;
  80.     }
  81.  
  82.     /* return successfully */
  83.     return (TRUE);
  84. }
  85.  
  86. /* db_fcode - free a code array */
  87. db_fcode(slptr)
  88.   struct sel *slptr;
  89. {
  90.     /* make sure there is a where clause */
  91.     if (slptr->sl_where == NULL)
  92.         return;
  93.  
  94.     /* free the literals */
  95.     freelit(slptr->sl_where);
  96.  
  97.     /* free the code array */
  98.     free(slptr->sl_where);
  99. }
  100.  
  101. /* operator - insert an operator into the code array */
  102. static int operator(opr)
  103.   int (*opr)();
  104. {
  105.     /* insert the operator */
  106.     if (cndx < CODEMAX)
  107.         code[cndx++].c_operator = opr;
  108.     else
  109.         return (db_ferror(CDSIZE));
  110.  
  111.     /* return successfully */
  112.     return (TRUE);
  113. }
  114.  
  115. /* operand - insert an operand into the code array */
  116. static int operand(opr)
  117.   struct operand *opr;
  118. {
  119.     /* insert the push operator */
  120.     if (!operator(db_xpush))
  121.         return (FALSE);
  122.  
  123.     /* insert the operand */
  124.     if (cndx < CODEMAX)
  125.         code[cndx++].c_operand = opr;
  126.     else
  127.         return (db_ferror(CDSIZE));
  128.  
  129.     /* return successfully */
  130.     return (TRUE);
  131. }
  132.  
  133. /* expr - compile an expression */
  134. static int expr(result)
  135.   int *result;
  136. {
  137.     int lval,rval;
  138.  
  139.     if (!land(&lval))
  140.         return (FALSE);
  141.     while (db_token() == '|') {
  142.         db_ntoken();
  143.         if (!land(&rval))
  144.             return (FALSE);
  145.         if (!operator(db_xor))
  146.             return (FALSE);
  147.     }
  148.     *result = lval;
  149.     return (TRUE);
  150. }
  151.  
  152. static int land(result)
  153.   int *result;
  154. {
  155.     int lval,rval;
  156.  
  157.     if (!relat(&lval))
  158.         return (FALSE);
  159.     while (db_token() == '&') {
  160.         db_ntoken();
  161.         if (!relat(&rval))
  162.             return (FALSE);
  163.         if (!operator(db_xand))
  164.             return (FALSE);
  165.     }
  166.     *result = lval;
  167.     return (TRUE);
  168. }
  169.  
  170. static int relat(result)
  171.   int *result;
  172. {
  173.     int lval,rval;
  174.     int tkn;
  175.  
  176.     if (!primary(&lval))
  177.         return (FALSE);
  178.     while (db_token() <= LSS && dbv_token >= GTR) {
  179.         tkn = db_ntoken();
  180.         if (!primary(&rval))
  181.             return (FALSE);
  182.         switch (tkn) {
  183.         case LSS:
  184.                 if (!operator(db_xlss))
  185.                     return (FALSE);
  186.                 break;
  187.         case LEQ:
  188.                 if (!operator(db_xleq))
  189.                     return (FALSE);
  190.                 break;
  191.         case EQL:
  192.                 if (!operator(db_xeql))
  193.                     return (FALSE);
  194.                 break;
  195.         case NEQ:
  196.                 if (!operator(db_xneq))
  197.                     return (FALSE);
  198.                 break;
  199.         case GEQ:
  200.                 if (!operator(db_xgeq))
  201.                    return (FALSE);
  202.                 break;
  203.         case GTR:
  204.                 if (!operator(db_xgtr))
  205.                     return (FALSE);
  206.                 break;
  207.         }
  208.     }
  209.     *result = lval;
  210.     return (TRUE);
  211. }
  212.  
  213. static int primary(result)
  214.   int *result;
  215. {
  216.     int val;
  217.     int tkn;
  218.  
  219.     if (db_token() == '~') {
  220.         tkn = db_ntoken();
  221.         if (!primary(&val))
  222.             return (FALSE);
  223.         switch (tkn) {
  224.         case '~':
  225.                 if (!operator(db_xnot))
  226.                     return (FALSE);
  227.                 break;
  228.         }
  229.     }
  230.     else
  231.         if (!factor(&val))
  232.             return (FALSE);
  233.     *result = val;
  234.     return (TRUE);
  235. }
  236.  
  237. static int factor(result)
  238.   int *result;
  239. {
  240.     int val;
  241.  
  242.     if (db_token() == '(') {
  243.         db_ntoken();
  244.         if (!expr(&val))
  245.             return (FALSE);
  246.         if (db_token() != ')')
  247.             return (db_ferror(SYNTAX));
  248.         db_ntoken();
  249.     }
  250.     else
  251.         if (!get_operand(&val))
  252.             return (FALSE);
  253.     *result = val;
  254.     return (TRUE);
  255. }
  256.  
  257. /* get_operand - get an operand (number, string, or attribute) */
  258. static int get_operand(result)
  259.   int *result;
  260. {
  261.     /* determine operand type */
  262.     if (db_ntoken() == NUMBER)
  263.         return (get_number(result));
  264.     else if (dbv_token == ID)
  265.         return (get_attr(result));
  266.     else if (dbv_token == STRING)
  267.         return (get_string(result));
  268.     else
  269.         return (db_ferror(SYNTAX));
  270. }
  271.  
  272. /* get_attr - get an attribute argument */
  273. static int get_attr(result)
  274.   int *result;
  275. {
  276.     struct operand *opr;
  277.     char rname[RNSIZE+1],aname[ANSIZE+1];
  278.     char *aptr; int atype,alen;
  279.  
  280.     /* save the attribute name */
  281.     stccpy(aname,dbv_tstring,ANSIZE); aname[ANSIZE] = EOS;
  282.  
  283.     /* check for a "." indicating a qualified attribute name */
  284.     if (db_token() == '.') {
  285.         db_ntoken();
  286.  
  287.         /* the previous ID was really a relation name */
  288.         strcpy(rname,aname);
  289.  
  290.         /* check for the real attribute name */
  291.         if (db_ntoken() != ID)
  292.             return (db_ferror(SYNTAX));
  293.  
  294.         /* save the attribute name */
  295.         stccpy(aname,dbv_tstring,ANSIZE); aname[ANSIZE] = EOS;
  296.  
  297.         /* lookup the attribute name */
  298.         if (!db_sattr(selptr,rname,aname,&atype,&aptr,&alen))
  299.             return (FALSE);
  300.     }
  301.     else
  302.         if (!db_sattr(selptr,NULL,aname,&atype,&aptr,&alen))
  303.             return (FALSE);
  304.  
  305.     /* get a new operand structure */
  306.     if ((opr = malloc(sizeof(struct operand))) == NULL)
  307.         return (db_ferror(INSMEM));
  308.  
  309.     /* initialize the new operand structure */
  310.     opr->o_type = ATTR;
  311.     opr->o_value.ov_char.ovc_type = atype;
  312.     opr->o_value.ov_char.ovc_string = aptr;
  313.     opr->o_value.ov_char.ovc_length = alen;
  314.  
  315.     /* insert the operand into the code array */
  316.     if (!operand(opr)) {
  317.         free(opr);
  318.         return (FALSE);
  319.     }
  320.  
  321.     /* store operand type */
  322.     *result = atype;
  323.  
  324.     /* return successfully */
  325.     return (TRUE);
  326. }
  327.  
  328. /* get_number - get a numeric operand */
  329. static int get_number(result)
  330.   int *result;
  331. {
  332.     struct operand *opr;
  333.  
  334.     /* get a new operand structure */
  335.     if ((opr = malloc(sizeof(struct operand))) == NULL)
  336.         return (db_ferror(INSMEM));
  337.  
  338.     /* initialize the new operand structure */
  339.     opr->o_type = LITERAL;
  340.     if ((opr->o_value.ov_char.ovc_string =
  341.                 malloc(strlen(dbv_tstring)+1)) == NULL) {
  342.         free(opr);
  343.         return (db_ferror(INSMEM));
  344.     }
  345.     opr->o_value.ov_char.ovc_type = TNUM;
  346.     strcpy(opr->o_value.ov_char.ovc_string,dbv_tstring);
  347.     opr->o_value.ov_char.ovc_length = strlen(dbv_tstring);
  348.  
  349.     /* insert the operand into the code array */
  350.     if (!operand(opr)) {
  351.         free(opr->o_value.ov_char.ovc_string); free(opr);
  352.         return (FALSE);
  353.     }
  354.  
  355.     /* operand type is number */
  356.     *result = TNUM;
  357.  
  358.     /* return successfully */
  359.     return (TRUE);
  360. }
  361.  
  362. /* get_string - get a string operand */
  363. static int get_string(result)
  364.   int *result;
  365. {
  366.     struct operand *opr;
  367.  
  368.     /* get a new operand structure */
  369.     if ((opr = malloc(sizeof(struct operand))) == NULL)
  370.         return (db_ferror(INSMEM));
  371.  
  372.     /* initialize the new operand structure */
  373.     opr->o_type = LITERAL;
  374.     if ((opr->o_value.ov_char.ovc_string =
  375.                 malloc(strlen(dbv_tstring)+1)) == NULL) {
  376.         free(opr);
  377.         return (db_ferror(INSMEM));
  378.     }
  379.     opr->o_value.ov_char.ovc_type = TCHAR;
  380.     strcpy(opr->o_value.ov_char.ovc_string,dbv_tstring);
  381.     opr->o_value.ov_char.ovc_length = strlen(dbv_tstring);
  382.  
  383.     /* insert the operand into the code array */
  384.     if (!operand(opr)) {
  385.         free(opr->o_value.ov_char.ovc_string); free(opr);
  386.         return (FALSE);
  387.     }
  388.  
  389.     /* operand type is character */
  390.     *result = TCHAR;
  391.  
  392.     /* return successfully */
  393.     return (TRUE);
  394. }
  395.  
  396. /* freelit - free the literals in a code array */
  397. static freelit(cptr)
  398.   union codecell *cptr;
  399. {
  400. #ifdef Lattice
  401.     int (*dns)();  /*dns*/
  402.     for (; (*cptr).c_operator != (dns=db_xstop); cptr++)  /*dns*/
  403.         if ((*cptr).c_operator == (dns=db_xpush) )        /*dns*/
  404. #else
  405.     for (; (*cptr).c_operator != db_xstop; cptr++)
  406.         if ((*cptr).c_operator == db_xpush )
  407. #endif
  408.             if ((*++cptr).c_operand->o_type == LITERAL)
  409.                 free((*cptr).c_operand->o_value.ov_char.ovc_string);
  410. }
  411.  
  412.